package solutions.ferpa.ztest.intf;

import br.com.telescope.adsrt.dom.DomTextLong;
import br.com.telescope.adsrt.lib.*;
import br.com.telescope.t2.ConnectionManager;
import br.com.telescope.t2.ServiceModel;
import br.com.telescope.t2.config.Config;
import br.com.telescope.t2.config.PropertiesFileConfigHandler;
import br.com.telescope.t2.exception.ApplicationRuntimeException;
import br.com.telescope.t2.feature.CustomFeature;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.sql.*;
import java.sql.SQLException;
import javax.sql.DataSource;
import solutions.ferpa.ztest.ent.*;

/**
 * Configurações do servidor.
 * <p>
 * Interface que permite configurar os parâmetros básicos de configuração 
 * do servidor da aplicação. Normalmente, isso se restringe aos 
 * parâmetros de configuração do banco de dados.
 * <P>
 * A tela apresenta os parâmetros atuais. Caso não existirem, a própria 
 * interface gera uma sugestão para os mesmos.
 * <P>
 * Os parâmetros são todos apresentados em um único campo do tipo texto 
 * com várias linhas no formato PARAMETRO=VALOR. O usuário pode editar 
 * livremente e então salvar.
 * <P>
 * 
 * <P>
 * Telescope origin: RTCONFIG.CFG_CONFIG
 * <P>
 * @author TELESCOPE - Build task T2 Web Interface Generator
 * <P>
 * @version 0.1
 */
public class CfgConfig extends ServiceModel {
    
    // <editor-fold defaultstate="collapsed" desc="Generated Code">
    public static final String GLOBAL_NAME = "RTCONFIG.CFG_CONFIG";
    
    @Override
    public String globalName() {
        return GLOBAL_NAME;
    }
    
    {
        setTitle("Configurações do servidor");
    }
    
    
    // Record items
    private DomTextLong aProperties;
    
    // Query items
    
    @Override
    public void initAttributes() {
        
        aProperties = new DomTextLong();
        aProperties.context(ctx).name("PROPERTIES").label("Properties").unbound(true);
        
    }
    
    @Override
    public String getDefaultOrderBy() {
        return "";
    }
    // </editor-fold>
    
    // <editor-fold defaultstate="collapsed" desc="CONFIG">
    public class FConfig extends CustomFeature {
        
        @Override
        public void initForm() {
            addField(aProperties, "opt");
        }
        
        @Override
        public void posDisplay() {
            try {
                testarDatasources();
            } catch (AdsException ex) {
                throw new ApplicationRuntimeException(ex);
            }
        }
        
        @Override
        public void preDisplay() {
            try {
                salvar();
                lerArquivo();
            } catch (AdsException ex) {
                throw new ApplicationRuntimeException(ex);
            }
        }
        
        @Override
        public void onAction() {
            addSubmit(getFeature("CONFIG")).label("Salvar").shortCutKey("F3");
        }
        
        {
            setFeatureName("CONFIG");
            setTitle("Salvar");
            setShortCutKey("F3");
            setPrimary(false);
        }
    }
    // </editor-fold>
    
    // <editor-fold defaultstate="collapsed" desc="initFeatures">
    
    @Override
    protected void initFeatures() {
        addFeature(new FConfig());
        super.initFeatures();
    }
    
    @Override
    public String getDefaultFeature() {
        return "CONFIG";
    }
    // </editor-fold>
    
    // <editor-fold defaultstate="collapsed" desc="Getters and Setters">
    
    public String getProperties() {
        return aProperties.getValue();
    }
    
    public void setProperties(String value) {
        this.aProperties.setValue(value);
    }
    // </editor-fold>
    
    /**
     * Ler arquivo.
     * <p>
     * Esta rotina lê o arquivo de configuração local do servidor.
     * <P>
     * Caso não encontrar, gera uma sugestão para o conteúdo deste arquivo.
     * <P>
     */
    private void lerArquivo() throws AdsException {
        // <user-code id="800140" parentId="800136" hashcode="4c986fad" length="1073">
        // import java.io.FileReader;
        // import br.com.telescope.t2.config.PropertiesFileConfigHandler;
        
        BufferedReader reader = null;
        StringBuilder text = new StringBuilder();
        try {
            PropertiesFileConfigHandler pfch = new PropertiesFileConfigHandler();
            reader = new BufferedReader( new FileReader(pfch.getFileName()));
            String line;
            while ((line = reader.readLine()) != null) {
                text.append(line).append("\n");
            } 
            reader.close();
        } catch (IOException ignore) {
            String appname = ctx.getServletContext().getServletContextName().toLowerCase();
            text.append("CONFIG.DB.DEFAULT.URL=jdbc:postgresql://localhost/" + appname + "\n"
                    + "CONFIG.DB.DEFAULT.DRIVER=org.postgresql.Driver\n"
                    + "CONFIG.DB.DEFAULT.USER=" + appname + "\n"
                    + "CONFIG.DB.DEFAULT.PASSWORD=secret\n"
                    + "CONFIG.DB.LOG.URL=jdbc:postgresql://localhost/" + appname + "\n"
                    + "CONFIG.DB.LOG.USER=" + appname + "\n"
                    + "CONFIG.DB.LOG.PASSWORD=secret\n");
        }
        aProperties.setValue(text.toString());
        // </user-code>
    }
    
    /**
     * Salvar.
     * <p>
     * Salva as parâmetros de configuração no servidor.
     * <P>
     * Caso o arquivo não exista, ou que um dos diretórios do caminho também 
     * não existam, a rotina cria. Esta rotina exige direitos de acesso para 
     * escrever nas pastas do usuário que está executando o servidor (ex: 
     * tomcat).
     * <P>
     */
    private void salvar() throws AdsException {
        // <user-code id="800132" parentId="800128" hashcode="-6135ccc4" length="719">
        // import java.io.File;
        // import java.io.FileWriter;
        // import br.com.telescope.t2.config.Config;
        // import br.com.telescope.t2.ConnectionManager;
        
        String text = ctx.getParameter("A_PROPERTIES");
        if (!text.isEmpty()) {
            FileWriter writer = null;
            try {
                PropertiesFileConfigHandler pfch = new PropertiesFileConfigHandler();
                String fileName = pfch.getFileName();
                (new File(fileName)).getParentFile().mkdirs();
                writer = new FileWriter(fileName);
                writer.write(text);
                writer.close();
                ctx.p("Configurações salvas em " + fileName);
            } catch (IOException ignore) {
            }
            ConnectionManager.refresh();
            Config.getInstance().refresh();
        }
        // </user-code>
    }
    
    /**
     * Testar Datasources.
     * <p>
     * Botão que permite ao usuário testar os datasources configurados.
     * <P>
     */
    private void testarDatasources() throws AdsException {
        // <user-code id="818722" parentId="818715" hashcode="-50ae3d23" length="512">
        // import java.sql.*;
        // import javax.sql.DataSource;
        Config cfg = Config.getInstance().getConfig("CONFIG.DB");
        ctx.p("<h2>DataSources status</h2><ul>");
        for (String dsname : cfg.getRoots()) {
            String message;
            try {
                DataSource ds = ConnectionManager.getDataSource(dsname);
                ds.getConnection().close();
                message = "OK";
            } catch (SQLException ex) {
                message = ex.getMessage();
            }
            ctx.p("<li>" + dsname + " - " + message + "</li>");
        }
        ctx.p("</ul><p>");
        // </user-code>
    }
}
